<?php
/**
 * Each engineer has a duty to keep the code elegant
 * Created by wolffy.
 * Author @wolffy<13750088090@sina.cn>
 * Date: 2018/9/2
 * Time: 15:13
 */
namespace App\Services;

use App\Repositories\RepaymentAccountWithdrawRepository;
use App\Repositories\ThreeApiErrorLogsRepository;
use App\Repositories\UserCreditCardRepository;
use App\Repositories\UserPassageRegisterRepository;
use App\Repositories\UserPassageRepository;
use App\Repositories\UserRepository;
use App\Services\LandingRepaymentC\LandingRepaymentCService;
use App\Services\LandingRepaymentE\LandingRepaymentEService;
use App\Services\RepaymentPay\LandingPayCService;
use App\Services\RepaymentPay\LargePayXService;

class RepaymentAccountWithdrawService extends CommonService
{
    protected $landingRepaymentCService;
    protected $landingRepaymentEService;
    protected $userRepository;
    protected $userPassageRepository;
    protected $userCreditCardRepository;
    protected $repaymentAccountWithdrawRepository;
    protected $userPassageRegisterRepository;
    protected $threeApiErrorLogsRepository;
    protected $landingPayCService;
    protected $largePayXService;

    public function __construct(LandingRepaymentCService $landingRepaymentCService,
                                LandingRepaymentEService $landingRepaymentEService,
                                UserRepository $userRepository,
                                UserPassageRepository $userPassageRepository,
                                UserCreditCardRepository $userCreditCardRepository,
                                RepaymentAccountWithdrawRepository $repaymentAccountWithdrawRepository,
                                UserPassageRegisterRepository $userPassageRegisterRepository,
                                ThreeApiErrorLogsRepository $threeApiErrorLogsRepository,
                                LandingPayCService $landingPayCService,
                                LargePayXService $largePayXService)
    {
        $this->landingRepaymentCService = $landingRepaymentCService;
        $this->landingRepaymentEService = $landingRepaymentEService;
        $this->userRepository = $userRepository;
        $this->userPassageRepository = $userPassageRepository;
        $this->userCreditCardRepository = $userCreditCardRepository;
        $this->repaymentAccountWithdrawRepository = $repaymentAccountWithdrawRepository;
        $this->userPassageRegisterRepository = $userPassageRegisterRepository;
        $this->threeApiErrorLogsRepository = $threeApiErrorLogsRepository;
        $this->landingPayCService = $landingPayCService;
        $this->largePayXService = $largePayXService;
    }

    /**
     * 账户余额
     * @param $user
     * @return \Illuminate\Http\JsonResponse
     */
    public function accountBalance($userId, $passageId = 1)
    {
        $redisKey = $this->repaymentAccountMoney() . 'passage_id_' . $passageId . '_user_id_' . $userId;
        if (!$this->redis()->exists($redisKey)) {
            //根据通道获取子商户号
            $userPassageMerchantNoC = $this->userPassageRepository->getSubMerchantNo(1, $userId);
            $userPassageMerchantNoE = $this->userPassageRepository->getSubMerchantNo(3, $userId);
            $resultC = $this->landingPayCService->subMerchantQuery(makeOrderNo(), $userPassageMerchantNoC);
            if ($resultC['response']['code'] == 0) {
                $amount = round($resultC['response']['data']['account_balance'], 2);
            } else {
                return $this->responseJson(400);
            }
            $resultE = $this->largePayXService->subMerchantQuery(makeOrderNo(), $userPassageMerchantNoE);
            if (isset($resultE['response']['data']['account_balance'])) {
                $amount = $amount + round($resultE['response']['data']['account_balance'], 2);
            }
            $amount = sprintf("%.2f", $amount);
            $this->redis()->setex($redisKey, 30, $amount);
            return $this->responseJson(0, ['account_balance' => $amount]);
        } else {
            $amount = $this->redis()->get($redisKey);
            $amount = sprintf("%.2f", $amount);
            return $this->responseJson(0, ['account_balance' => $amount]);
        }

    }

    /**
     * 提现
     */
    public function withdraw($request, $userId, $passageId)
    {
        if ($request->withdraw_money < 2) {
            return $this->responseJson(10600);//单笔提现最低金额2元
        }
        //是否有待执行和执行中的记录
//        $isHasRunOrNoRun = $this->repaymentPlanRepository->isExistRunOrNoRun($userId);
//        if (!empty($isHasRunOrNoRun)) {
//            return $this->responseJson(10602);//还款计划执行中不允许提现
//        }
        $userCreditCardRepository = $this->userCreditCardRepository->validateCreditCardIsUser($request->credit_id, $userId);
        if (empty($userCreditCardRepository)) {
            return $this->responseJson(10306);//信用卡不存在
        }
        //根据通道获取子商户号
        $userPassageMerchantNo = $this->userPassageRepository->getSubMerchantNo($passageId, $userId);
        //子商户号为空说明没有进行还款计划
        if (empty($userPassageMerchantNo)) {
            return $this->responseJson(10603);//未使用过还款计划不允许提现
        }
        //子商户绑卡
        $orderNo = makeOrderNo();
        $isBindCard = $this->userPassageRegisterRepository->isBindCard($passageId, $userId, $userCreditCardRepository->id);
        if (empty($isBindCard)) {
            $isHasSubMerchantBindCard = $this->landingRepaymentCService->subMerchantBindCard($orderNo, $userPassageMerchantNo,
                $userCreditCardRepository->bank_no, $userCreditCardRepository->bank_description);
            $errorRes = [
                'order_no' => $orderNo,
                'error_code' => $isHasSubMerchantBindCard['returncode'],
                'error_msg' => isset($isHasSubMerchantBindCard['message']) ? $isHasSubMerchantBindCard['message'] : $isHasSubMerchantBindCard['errtext'],
                'api_type' => 8
            ];
            if (isset($isHasSubMerchantBindCard['message']) && isset($isHasSubMerchantBindCard['returncode']) && $isHasSubMerchantBindCard['returncode'] == '0000') {
                $isBind = 1;
                $this->threeApiErrorLogsRepository->create($errorRes);
            } else {
                $this->threeApiErrorLogsRepository->create($errorRes);
                return $this->responseJson(10513);//子商户绑卡失败
            }
            $this->userPassageRegisterRepository->create([
                'order_no' => $orderNo,
                'passage_id' => $passageId,
                'user_id' => $userId,
                'card_id' => $userCreditCardRepository->id,
                'is_bind' => $isBind,
                'is_open' => 0,
            ]);
        }
        //提现
        $serviceCharge = 1;
        $result = $this->landingRepaymentCService->subMerchantWithDraw($orderNo, $userPassageMerchantNo,
            $userCreditCardRepository->bank_no, $request->withdraw_money, $serviceCharge);
        $errorData = [
            'order_no' => $orderNo,
            'error_code' => $result['returncode'],
            'error_msg' => isset($result['message']) ? $result['message'] : $result['errtext'],
            'api_type' => 9
        ];
        if (isset($result['message']) && isset($result['returncode'])) {
            $message = json_decode($result['message'], true);
            $data = [
                'withdraw_no' => $orderNo,
                'user_id' => $userId,
                'credit_card_id' => $userCreditCardRepository->id,
                'bank_no' => $userCreditCardRepository->bank_no,
                'bank_code' => $userCreditCardRepository->bank_code,
                'bank_description' => $userCreditCardRepository->bank_description,
                'withdraw_money' => $request->withdraw_money,
                'withdraw_service_charge' => $serviceCharge,
                'create_time' => time(),
                'sub_merchant_no' => $userPassageMerchantNo,
            ];
            if ($message['code'] == 'SUCCESS') {
                $data['withdraw_status'] = 4001;
                $this->repaymentAccountWithdrawRepository->create($data);
                $this->threeApiErrorLogsRepository->create($errorData);
                //清除还款金账户的缓存
                $redisKey = $this->repaymentAccountMoney() . 'passage_id_' . $passageId . '_user_id_' . $userId;
                $this->redis()->del($redisKey);
                return $this->responseJson(0);
            } else {
                $data['withdraw_status'] = 4003;
                $data['fail_message'] = $message['message'];
                $this->repaymentAccountWithdrawRepository->create($data);
                $this->threeApiErrorLogsRepository->create($errorData);
                return $this->responseJson(10601, [], false, $message['message'], $message['message']);
            }
        } else {
            $this->threeApiErrorLogsRepository->create($errorData);
            return $this->responseJson(400);
        }
    }

    public function tradeDetail($userId, $status, $page)
    {
        if (0 === $status) {
            $data = $this->repaymentAccountWithdrawRepository->getTradeRecordAll($userId, $page, 30);
        } else {
            $data = $this->repaymentAccountWithdrawRepository->getTradeRecordToStatus($userId, $status, $page, 30);
        }
        return $this->responseJson(0, $data);
    }
}